package com.gmlive.common.upload.plugin

import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import com.google.gson.Gson
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import org.gradle.api.Project
import org.json.JSONObject
import java.io.File
import java.math.BigInteger
import java.security.MessageDigest

/**
 * author: fanfeiyue
 * time: 2020/10/29
 * des:
 */
object DingTalkUtil {

    fun sendDingBuildApkMsg() {
        val client = OkHttpClient()

        val atMobiles = listOf("13798076537")

        val apkBuildInfo = ApkBuildInfo(
                appName = "77爱玩",
                branch = "origin/develop-2.1",
                buildUrl = "http://gmlivejenkins.vaiwan.com/job/ssvoice/",
                buildUser = "fanfeiyue@inke.cn",
                apkUrl = "http://gmlivepacker.vaiwan.com/ssvoice/31/77-v2.1.01-dev.apk",
                changesCommitUrl = "http://gmlivejenkins.vaiwan.com/job/ssvoice/31/changes",
                apkMD5 = "43e73f89bf6ae4bf5a84045d1d675035",
                apkSize = "42.21M",
                mappingUrl = "http://gmlivepacker.vaiwan.com/ssvoice/31/mapping.txt",
                versionName = "2.1.01-dev"
        )

        val paramStr = Gson().toJson(
                buildDingMsgModel(
                        apkBuildInfo = apkBuildInfo,
                        title = "[SDK助手提示]",
                        atMobiles = atMobiles
                )
        )

        val body = FormBody.create(MediaType.parse("application/json; charset=utf-8"), paramStr)

        val request = Request.Builder()
                .url("https://oapi.dingtalk.com/robot/send?access_token=a6c8970ffa88fa607adb7a3cf0991eb5ef88831c0184cd9f459ff3267ea7de8e")
                .post(body)
                .build()

        val response = client.newCall(request).execute()

        println("leaps ${response.body()?.string()}")
    }

    //    private fun getAtMobiles(atMobilesStr: String): List<String> {
    //        return atMobilesStr.replace('；', ';')
    //                .split(';')
    //                .map { it.trim() }
    //                .filter { it.isNotBlank() }
    //    }

    private fun buildDingMsgModel(
            apkBuildInfo: ApkBuildInfo,
            title: String = "",
            atMobiles: List<String> = listOf(),
            isAtAll: Boolean = false,
    ): DingMsgModel {

        val markdown = Action(
                title = title,
                text = buildActionMsgText(apkBuildInfo, atMobiles),
                //                btnOrientation = ORIENTATION_VERTICL,
                //                btns = mutableListOf<BtnActionInfo>().apply {
                //                    apkBuildInfo.apkUrl.takeIf { !it.isNullOrBlank() }?.let { add(BtnActionInfo("下载apk", it)) }
                //                    apkBuildInfo.changesCommitUrl.takeIf { !it.isNullOrBlank() }?.let { add(BtnActionInfo("提交记录", it)) }
                //                }
        )

        val at = At(
                atMobiles = atMobiles,
                isAtAll = isAtAll
        )

        return DingMsgModel(
                msgtype = "markdown",
                markdown = markdown,
                at = at
        )

    }

    private fun buildActionMsgText(apkBuildInfo: ApkBuildInfo, atMobiles: List<String> = listOf()): String {
        return apkBuildInfo.run {
            StringBuilder().apply {
                takeIf { !appName.isNullOrBlank() }?.let { append("### App: $appName").append("\n") }
                takeIf { !branch.isNullOrBlank() }?.let { append("- 分支: $branch").append("\n") }
                takeIf { !buildUrl.isNullOrBlank() }?.let { append("- JOB ID: [#$buildID](${buildUrl}${buildID}/)").append("\n") }
                takeIf { !buildUser.isNullOrBlank() }?.let { append("- 操作人: $buildUser").append("\n") }
                takeIf { !apkUrl.isNullOrBlank() }?.let { append("- apk下载: [点击下载]($apkUrl)").append("\n") }
                takeIf { !changesCommitUrl.isNullOrBlank() }?.let { append("- 提交记录: [点击查看]($changesCommitUrl)").append("\n") }
                takeIf { !apkMD5.isNullOrBlank() }?.let { append("- md5: $apkMD5").append("\n") }
                takeIf { !apkSize.isNullOrBlank() }?.let { append("- size: $apkSize").append("\n") }
                takeIf { !mappingUrl.isNullOrBlank() }?.let { append("- mapping: $mappingUrl").append("\n") }
                takeIf { !apkUrl.isNullOrBlank() }?.let { append("- 下载地址: $apkUrl").append("\n") }
                takeIf { !versionName.isNullOrBlank() }?.let { append("- version: $versionName").append("\n") }
                takeIf { uploadFir && !firAddress.isNullOrBlank() }?.let { append("- Fir地址: $firAddress").append("\n") }
                append("- 是否加固: $userReinforce").append("\n")

                append("\n")
                takeIf { !atMobiles.isNullOrEmpty() }?.let {
                    append("<font color=#1890ff face=\"黑体\">")

                    atMobiles.forEach {
                        append("@$it")
                    }

                    append("</font>")
                }

                takeIf { !buildDesc.isNullOrBlank() }?.let {
                    append("<font color=#000000 face=\"黑体\">")
                    append(buildDesc)
                    append("</font>")
                    append("\n")
                }

            }.toString()
        }
    }

    fun copy(project: Project) {
        project.gradle.startParameter.taskNames.forEach {
            println("leaps taskName:$it")
        }
        project.copy {
            val fromFile = "${project.buildDir}/outputs/apk/debug/SDKSample-v1.0.01.apk"
            val intoDir = "${project.buildDir}/outputs/apk/into/"
            println("leaps fromFile:$fromFile, intoDir:$intoDir, fileName:${File(fromFile).name.endsWith("apk")}")
            it.from(fromFile)
            it.into(intoDir)
        }
    }

    fun getUploadCert() {

        val bundleId = "com.gmlive.someone"
        val apiToken = "3d1bfdd171a9439ea0c57e6ba222b4a0"

        println("[uploadFir] bundleId = $bundleId, apiToken = $apiToken")

        val client = OkHttpClient()

        val bodyJsonObj = JSONObject().apply {
            put("type", "android")
            put("bundle_id", bundleId)
            put("api_token", apiToken)
        }

        println("[uploadFir] bodyJsonObj : ${bodyJsonObj.toString()}")

        val bodyReq = FormBody.create(MediaType.parse("application/json; charset=utf-8"), bodyJsonObj.toString())
        val req = Request.Builder()
                .url("http://api.bq04.com/apps")
                .post(bodyReq)
                .build()

        val response = client.newCall(req).execute()

        val result = response.body()?.string()
        println("[uploadFir] get upload cert response : $result")

        val binaryJSONObj = JSONObject(result).getJSONObject("cert").getJSONObject("binary")

        val uploadUrl = binaryJSONObj["upload_url"] as String
        val key = binaryJSONObj["key"] as String
        val token = binaryJSONObj["token"] as String

        println("[uploadFir] key = $key, token = $token, uploadUrl = $uploadUrl")
    }

    fun testMD5(project: Project) {
        val filePath = "/Users/fanfeiyue/AndroidStudioProjects/gmlivesdk/sample/build/outputs/debug/1.2.04_1204_publish_aijiami.apk"
        println("File md5:${md5Sum(File(filePath))}")
    }

    fun md5Sum(file: File): String {
        val md = MessageDigest.getInstance("MD5")
        file.forEachBlock(4096) { bytes, size ->
            md.update(bytes, 0, size)
        }

        return md.digest().map { String.format("%02x", it) }.joinToString(separator = "") { it }
    }

    fun findApkPath(project: Project) {
        val android = project.extensions.findByName("android") as BaseAppModuleExtension
        android.applicationVariants.all { variant ->
            variant.outputs.all { output ->
                // APK路径
                var outputFile: File? = null
                try {
                    outputFile = File(variant.packageApplicationProvider.get().outputDirectory.get().asFile.path, output.outputFile.name)
                } catch (e: Exception) {

                } finally {
                    outputFile = outputFile ?: output.outputFile
                }
                println("dir:${variant.packageApplicationProvider.get().outputDirectory.get().asFile.path}")
                println("fileName:${output.outputFile.name}")
                println("file path:${output.outputFile.path}")
            }
        }
    }

    fun getAtMobiles(atMobilesStr: String): List<String> {
        val result = atMobilesStr.replace('；', ';')
                .split(';')
                .map { it.trim() }
                .filter { it.isNotBlank() }
        println("leaps:$result")
        println("leaps:${result.size}")
        takeIf { !result.isNullOrEmpty() }?.let {
            println("leaps: ${result[0]}")
        }
        return result
    }

}